package com.db.utils;

import android.net.Uri;

import java.io.*;
import java.net.*;
import java.util.*;
import java.util.Map.Entry;

/**
 * Created by John on 2016/5/5.
 */
public class Downloader {


    public static String doDownload(String url, String method, String param, Map<String, String> headers) {//method  "GET":"POST"

        String result = "";
        StringBuilder builder = null;
        InputStream inputStream = null;
        HttpURLConnection conn = null;
        try {
            conn = (HttpURLConnection) new URL(url).openConnection();
            conn.setReadTimeout(30000);
            conn.setConnectTimeout(30000);
            conn.setRequestMethod(method);
            conn.setDoInput(true);
            if (headers != null) {
                for (Entry entry : headers.entrySet()) {
                    conn.setRequestProperty(entry.getKey().toString(), entry.getValue().toString());
                }
            }

            if ("POST".equals(method)) {
                conn.setDoOutput(true);
            }
            // Starts the query
            conn.connect();

            if ("POST".equals(method)) {
                DataOutputStream out = new DataOutputStream(conn.getOutputStream());
                out.write(param.getBytes());
                out.flush();
                out.close();
            }
            int status = conn.getResponseCode();
            if (status == 302 || status == 301) {
                String redirectLocation = conn.getHeaderField("Location");
//                System.out.println("redirectLocation:" + redirectLocation);
                LogUtil.logApp("Download", "redirectLocation:" + redirectLocation);
            }

            inputStream = conn.getInputStream();
            if (inputStream != null) {
//            	File parent = new File(savePath).getParentFile();
//                if(!parent.exists()){
//                    parent.mkdirs();
//                }
                BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream, "utf8"));
                builder = new StringBuilder();
                String s = null;
                for (s = reader.readLine(); s != null; s = reader.readLine()) {
                    builder.append(s);
                }
                result = builder.toString();
//                LogUtil.log("download:"+builder.toString());
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
//        LogUtil.log("url" + url + ", result:" + result);
        return result;
    }

    public static String doDownloadRedirect(String url, String method, String param, Map<String, String> headers, IpInfo.DataBean data, StringBuffer referrer) throws IOException {//method  "GET":"POST"
        Uri uri = Uri.parse(url);
        System.out.println(uri.getScheme());
//        if ("market".equals(uri.getScheme())
//                || "intent".equals(uri.getScheme())
//                || "play.google.com".equals(uri.getHost())
//                || url.endsWith(".apk")
//                || uri.getPath().endsWith(".apk")
//                || "apps.apple.com".equals(uri.getHost())
//                || "itunes.apple.com".equals(uri.getHost())) {
//            referrer.append(uri.getQueryParameter("referrer"));
//            return null;
//        }

        // 测试代码
        if ("market".equals(uri.getScheme()) || "intent".equals(uri.getScheme())
                || url.endsWith(".apk") || uri.getPath().endsWith(".apk")
                || "view.adjust.com".equals(uri.getHost()) || "play.google.com".equals(uri.getHost())
                || "apps.apple.com".equals(uri.getHost()) || "itunes.apple.com".equals(uri.getHost())) {
            referrer.append(uri.getQueryParameter("referrer"));
            return null;
        }

        String result = "";
        StringBuilder builder = null;
        InputStream inputStream = null;
        HttpURLConnection conn = null;
        try {
            LogUtil.log("url:" + url + "--method:" + method + "--param:" + param);
            if (data != null) {
                conn = (HttpURLConnection) new URL(url).openConnection(ProxyUtil.createProxy(data));
            } else {
                conn = (HttpURLConnection) new URL(url).openConnection();
            }
            conn.setReadTimeout(20000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod(method);
            conn.setDoInput(true);
            conn.setInstanceFollowRedirects(false);
            if (headers != null) {
                for (Entry entry : headers.entrySet()) {
                    conn.setRequestProperty(entry.getKey().toString(), entry.getValue().toString());
                }
            }


            if ("POST".equals(method)) {
                conn.setDoOutput(true);
            }
            // Starts the query
            conn.connect();


            if ("POST".equals(method)) {
                DataOutputStream out = new DataOutputStream(conn.getOutputStream());
                out.write(param.getBytes());
                out.flush();
                out.close();
            }
            int status = conn.getResponseCode();
            LogUtil.log("url:" + url + ", response code:" + status);
            if (status == 302 || status == 301) {
                String redirectLocation = conn.getHeaderField("Location");
                System.out.println("redirectLocation:" + redirectLocation);
                doDownloadRedirect(redirectLocation, "GET", null, headers, data, referrer);
                conn.disconnect();
                return null;
            }
            if (status == 200 || status == 201 || status == 202) {
                inputStream = conn.getInputStream();
            } else {
                inputStream = conn.getErrorStream();
            }
            if (inputStream != null) {
//            	File parent = new File(savePath).getParentFile();
//                if(!parent.exists()){
//                    parent.mkdirs();
//                }
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(inputStream, "utf8"));
                builder = new StringBuilder();
                String s = null;
                for (s = reader.readLine(); s != null; s = reader.readLine()) {
                    builder.append(s);
                }
                result = builder.toString();
//                LogUtil.log("download:"+builder.toString());

            }

        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        LogUtil.log("url" + url + ", result:" + result);
        return result;
    }

    public static String doDownloadRedirect(String url, String method, String param, Map<String, String> headers, IpInfo.DataBean data, StringBuffer referrer, List<String> url302List) throws IOException {//method  "GET":"POST"
        Uri uri = Uri.parse(url);
        System.out.println(uri.getScheme());

        if ("market".equals(uri.getScheme())
                || "intent".equals(uri.getScheme())
                || "play.google.com".equals(uri.getHost())
                || url.endsWith(".apk")
                || uri.getPath().endsWith(".apk")
                || "view.adjust.com".equals(uri.getHost())
                || "apps.apple.com".equals(uri.getHost())
                || "itunes.apple.com".equals(uri.getHost())) {
            referrer.append(uri.getQueryParameter("referrer"));
            url302List.add(url);
            return null;
        }

        String result = "";
        StringBuilder builder = null;
        InputStream inputStream = null;
        HttpURLConnection conn = null;
        try {
            LogUtil.log("url:" + url + "--method:" + method + "--param:" + param);
            if (data != null) {
                conn = (HttpURLConnection) new URL(url).openConnection(ProxyUtil.createProxy(data));
            } else {
                conn = (HttpURLConnection) new URL(url).openConnection();
            }
            conn.setReadTimeout(20000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod(method);
            conn.setDoInput(true);
            conn.setInstanceFollowRedirects(false);
            if (headers != null) {
                for (Entry entry : headers.entrySet()) {
                    conn.setRequestProperty(entry.getKey().toString(), entry.getValue().toString());
                }
            }


            if ("POST".equals(method)) {
                conn.setDoOutput(true);
            }
            // Starts the query
            conn.connect();


            if ("POST".equals(method)) {
                DataOutputStream out = new DataOutputStream(conn.getOutputStream());
                out.write(param.getBytes());
                out.flush();
                out.close();
            }
            int status = conn.getResponseCode();
            LogUtil.log("url:" + url + ", response code:" + status);
            if (status == 302 || status == 301 || status == 307) {
                String redirectLocation = conn.getHeaderField("Location");
                if (redirectLocation == null || redirectLocation.length() < 2) {
                    // 临时重定向和永久重定向location的大小写有区分
                    redirectLocation = conn.getHeaderField("location");
                }
                System.out.println("redirectLocation:" + redirectLocation);
                doDownloadRedirect(redirectLocation, "GET", null, headers, data, referrer, url302List);
                conn.disconnect();
                return null;
            }

            if (status == 200 || status == 201 || status == 202 || status == 400) {
                inputStream = conn.getInputStream();

            } else {
                inputStream = conn.getErrorStream();
            }
            if (inputStream != null) {
//            	File parent = new File(savePath).getParentFile();
//                if(!parent.exists()){
//                    parent.mkdirs();
//                }
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(inputStream, "utf8"));
                builder = new StringBuilder();
                String s = null;
                for (s = reader.readLine(); s != null; s = reader.readLine()) {
                    builder.append(s);
                }
                result = builder.toString();
//                LogUtil.log("download:"+builder.toString());

                if (result.contains("url=")) {
                    result = result.substring(result.indexOf("url=") + 4);
                    url302List.add(result.substring(0, result.indexOf("\"")));
                } else if (result.contains("URL=")) {
                    result = result.substring(result.indexOf("URL=") + 4);
                    url302List.add(result.substring(0, result.indexOf("\"")));
                } else if (result.contains("href=")) {
                    result = result.substring(result.indexOf("href=") + 6);
                    url302List.add(result.substring(0, result.indexOf("\"")));
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        LogUtil.log("url:" + url + ", result:" + result);
        return result;
    }

    public static String doDownloadRedirect(String uuid, int taskId, String url, String method, String param, Map<String, String> headers, IpInfo.DataBean data, StringBuffer referrer, List<String> url302List) throws IOException {//method  "GET":"POST"
        Uri uri = Uri.parse(url);
        System.out.println(uri.getScheme());

        if ("market".equals(uri.getScheme())
                || "intent".equals(uri.getScheme())
                || "play.google.com".equals(uri.getHost())
                || url.endsWith(".apk")
                || uri.getPath().endsWith(".apk")
                || "view.adjust.com".equals(uri.getHost())
                || "apps.apple.com".equals(uri.getHost())
                || "itunes.apple.com".equals(uri.getHost())) {
            referrer.append(uri.getQueryParameter("referrer"));
            url302List.add(url);
            return null;
        }

        String result = "";
        StringBuilder builder = null;
        InputStream inputStream = null;
        HttpURLConnection conn = null;
        try {
//            LogUtil.log2test(null, "uuid:" + uuid + ", taskId:" + taskId + "--url:" + url + "--method:" + method + "--param:" + param);
            System.out.println("uuid:" + uuid + "taskId:" + taskId + "--url:" + url + "--method:" + method + "--param:" + param);
            if (data != null) {
                conn = (HttpURLConnection) new URL(url).openConnection(ProxyUtil.createProxy(uuid, data));
            } else {
                conn = (HttpURLConnection) new URL(url).openConnection();
            }
            conn.setReadTimeout(20000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod(method);
            conn.setDoInput(true);
            // 禁止重定向
            conn.setInstanceFollowRedirects(false);

            if (headers != null) {
                for (Entry entry : headers.entrySet()) {
                    conn.setRequestProperty(entry.getKey().toString(), entry.getValue().toString());
                }
            }


            if ("POST".equals(method)) {
                conn.setDoOutput(true);
            }
            // Starts the query
            conn.connect();


            if ("POST".equals(method)) {
                DataOutputStream out = new DataOutputStream(conn.getOutputStream());
                out.write(param.getBytes());
                out.flush();
                out.close();
            }
            int status = conn.getResponseCode();
            LogUtil.log("url:" + url + ", response code:" + status);
            if (status == 302 || status == 301) {
                String redirectLocation = conn.getHeaderField("Location");
                if (redirectLocation == null || redirectLocation.length() < 2) {
                    // 临时重定向和永久重定向location的大小写有区分
                    redirectLocation = conn.getHeaderField("location");
                }
                System.out.println("redirectLocation:" + redirectLocation);
                doDownloadRedirect(uuid, taskId, redirectLocation, "GET", null, headers, data, referrer, url302List);
                conn.disconnect();
                return null;
            }

            if (status == 200 || status == 201 || status == 202) {
                inputStream = conn.getInputStream();

            } else {
                inputStream = conn.getErrorStream();
            }
            if (inputStream != null) {
//            	File parent = new File(savePath).getParentFile();
//                if(!parent.exists()){
//                    parent.mkdirs();
//                }
                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(inputStream, "utf8"));
                builder = new StringBuilder();
                String s = null;
                for (s = reader.readLine(); s != null; s = reader.readLine()) {
                    builder.append(s);
                }
                result = builder.toString();
//                LogUtil.log("download:"+builder.toString());

                if (result.contains("url=")) {
                    result = result.substring(result.indexOf("url=") + 4);
                    url302List.add(result.substring(0, result.indexOf("\"")));
                } else if (result.contains("URL=")) {
                    result = result.substring(result.indexOf("URL=") + 4);
                    url302List.add(result.substring(0, result.indexOf("\"")));
                } else if (result.contains("href=")) {
                    result = result.substring(result.indexOf("href=") + 6);
                    url302List.add(result.substring(0, result.indexOf("\"")));
                }
            }

        } catch (IOException e) {
            e.printStackTrace();
//            LogUtil.log2test("Redirect Exception", "url=" + url + ", Exception Message" + e.getMessage());
            System.out.println("Redirect Exception" + ", url=" + url + ", Exception Message" + e.getMessage());
            throw e;
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

//        LogUtil.log2test("Redirect Url Success", "uuid:" + uuid + ", taskId:" + taskId + ", url:" + url + ", result:" + result
//                + ", Ip:" + data.getIp() + ", proxyIp:" + data.getProxyIp()
//                + ", iso:" + data.getIso() + ", mcc:" + data.getMcc()
//        );

        System.out.println("Redirect Url Success" + ", uuid:" + uuid + ", taskId:" + taskId + ", url:" + url + ", result:" + result
                + ", Ip:" + data.getIp() + ", proxyIp:" + data.getProxyIp()
                + ", iso:" + data.getIso() + ", mcc:" + data.getMcc());

        return result;
    }


    public static String doDownloadWithJson(String url, String method, String param) {//method  "GET":"POST"
        String result = "";
        StringBuilder builder = null;
        InputStream inputStream = null;
        HttpURLConnection conn = null;
        try {
            LogUtil.log("url:" + url + "--method:" + method + "--param:" + param);
            conn = (HttpURLConnection) new URL(url).openConnection();
            conn.setReadTimeout(20000);
            conn.setConnectTimeout(15000);
            conn.setRequestMethod(method);
            conn.setDoInput(true);
            conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");

            if ("POST".equals(method)) {
                conn.setDoOutput(true);
            }
            // Starts the query
            conn.connect();


            if ("POST".equals(method)) {
                DataOutputStream out = new DataOutputStream(conn.getOutputStream());
                out.write(param.getBytes());
                out.flush();
                out.close();
            }
            int status = conn.getResponseCode();
            LogUtil.log("url:" + url + ",response code:" + status);
            if (status == 302) {
                System.out.println(conn.getHeaderField("Location"));
            }

            inputStream = conn.getInputStream();
            if (inputStream != null) {
//            	File parent = new File(savePath).getParentFile();
//                if(!parent.exists()){
//                    parent.mkdirs();
//                }

                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(inputStream, "utf8"));
                builder = new StringBuilder();
                String s = null;
                for (s = reader.readLine(); s != null; s = reader.readLine()) {
                    builder.append(s);
                }
                result = builder.toString();
//                LogUtil.log("download:"+builder.toString());

            }

        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e1) {
            e1.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }


        LogUtil.log("url" + url + ", result:" + result);
        return result;
    }


    public static String doUploadFile(String url, Map<String, String> param, String fieldName, File uploadFile) {
        String result = "";
        StringBuilder builder = null;
        InputStream inputStream = null;
        String end = "\r\n";
        String twoHyphens = "----";
        String boundary = "**************";
//        String boundary =  UUID.randomUUID().toString();
        HttpURLConnection conn;
        try {
            DataOutputStream out;
            conn = (HttpURLConnection) new URL(url).openConnection();
            conn.setDoInput(true);
            conn.setDoOutput(true);
            conn.setUseCaches(false);
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Connection", "Keep-Alive");
            conn.setRequestProperty("Charset", "UTF-8");
//            DataOutputStream out = new DataOutputStream(new FileOutputStream(FilePathUtils.registerAccountFilePath + "tt123.txt"));

            if (uploadFile != null) {
                conn.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + twoHyphens + boundary);
                out = new DataOutputStream(conn.getOutputStream());
//                out = new DataOutputStream(new FileOutputStream(FilePathUtils.registerAccountFilePath + "tt123.txt"));
                Set<String> keys = param.keySet();
                for (String key : keys) {
                    out.writeBytes(twoHyphens + boundary + end);
                    out.writeBytes("Content-Disposition: form-data; name=\"" + key + "\"" + end);
                    out.writeBytes("Content-Type: text/plain" + end);
                    out.writeBytes(end);
                    out.writeBytes(param.get(key));
                    out.writeBytes(end);
                }
                out.writeBytes(twoHyphens + boundary + end);
                out.writeBytes("Content-Disposition: form-data; name=\"" + fieldName + "\"; filename=\"" + uploadFile.getName() + "\"" + end);
                out.writeBytes("Content-Type: application/octet-stream" + end);
                out.writeBytes(end);

                FileInputStream fis = new FileInputStream(uploadFile);
                byte[] buffer = new byte[4096];
                int count = 0;
                while ((count = fis.read(buffer)) != -1) {
                    out.write(buffer, 0, count);
                }
                fis.close();
                out.writeBytes(end);
                out.writeBytes(twoHyphens + boundary + twoHyphens);
            } else {
                conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
                out = new DataOutputStream(conn.getOutputStream());
                List<String> keys = new ArrayList<String>(param.keySet());
                Collections.sort(keys);

                StringBuilder sb = new StringBuilder();
                for (int i = 0; i < keys.size(); i++) {
                    String key = keys.get(i);
                    String value = param.get(key);
                    if (i == keys.size() - 1) {
                        sb.append(key).append("=").append(value);
                    } else {
                        sb.append(key).append("=").append(value).append("&");
                    }
                }
                out.writeBytes(sb.toString());
            }

            out.flush();

            inputStream = conn.getInputStream();
            if (inputStream != null) {
//            	File parent = new File(savePath).getParentFile();
//                if(!parent.exists()){
//                    parent.mkdirs();
//                }

                BufferedReader reader = new BufferedReader(
                        new InputStreamReader(inputStream, "utf8"));
                builder = new StringBuilder();
                String s = null;
                for (s = reader.readLine(); s != null; s = reader.readLine()) {
                    builder.append(s);
                }
                result = builder.toString();
//                LogUtil.log("download:"+builder.toString());
            }

        } catch (MalformedURLException e) {
            e.printStackTrace();

        } catch (IOException e1) {
            e1.printStackTrace();
        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return result;

    }
}
